package com.refusea.train.domain.helper

import com.refusea.train.domain.cache.SchoolCache
import com.refusea.train.domain.cache.UserCache
import com.refusea.train.domain.entity.School
import com.refusea.train.domain.entity.User
import com.refusea.train.domain.entity.User.Role
import com.refusea.train.domain.entity.User.Role.PARENT
import com.refusea.train.domain.entity.User.Role.PRINCIPAL
import com.refusea.train.domain.ex.BizEx
import com.refusea.train.domain.req.RegisterReq
import com.refusea.train.domain.tx.RegisterTx
import com.refusea.train.domain.vo.RegInfo
import com.refusea.train.utils.Codes
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.stereotype.Component

/**
 * @author Zhang Yan 2024/3/23
 **/
@Component
class RegisterHelper(
    private val passwordEncoder: PasswordEncoder,

    private val userCache: UserCache,
    private val schoolCache: SchoolCache,
    private val registerTx: RegisterTx,
) {

    fun register(req: RegisterReq) {

        val user = User(
            0,
            req.schoolId,
            req.name,
            req.loginId,
            passwordEncoder.encode(req.password),
            Role.valueOf(req.role),
            req.referrerId ?: 0,
            req.parentId ?: 0,
            null
        )

        if (user.role != PRINCIPAL) {
            schoolCache.get(user.schoolId) ?: throw BizEx.of("学校不存在")
            registerTx.register(user)
            return
        }

        val school = School(0, req.school, 0)
        registerTx.principalRegister(user, school)

        userCache.invalidate(user.schoolId)
    }

    fun regInfo(cat: Int, code: String): RegInfo {

        return when (cat) {
            // parent with referrer code
            1 -> {
                val (referrerId, schoolId) = Codes.decode(code)
                val school = schoolCache.get(schoolId) ?: throw BizEx.of("学校不存在")
                RegInfo(referrerId, school.id, school.name)
            }

            // child with parent id
            2 -> {
                val user = userCache.get(code.toInt()) ?: throw BizEx.of("用户不存在")
                if (user.role != PARENT) {
                    throw BizEx.of("参数错误")
                }
                val school = schoolCache.get(user.schoolId) ?: throw BizEx.of("学校不存在")
                RegInfo(null, school.id, school.name, user.name)
            }

            // teacher/referrer with school id
            3, 4 -> {
                val school = schoolCache.get(code.toInt()) ?: throw BizEx.of("学校不存在")
                RegInfo(null, school.id, school.name)
            }

            else -> throw BizEx.of("参数错误")
        }
    }

}
